home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / GAS211S2.ZIP / src / gas-211 / opcodes / h8500-di.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  8KB  |  331 lines

  1. /* Disassemble h8500 instructions.
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19.  
  20. #define DISASSEMBLER_TABLE
  21. #define DEFINE_TABLE
  22.  
  23. #include "h8500-opc.h"
  24. #include "dis-asm.h"
  25.  
  26. /* Maximum length of an instruction.  */
  27. #define MAXLEN 8
  28.  
  29. #include <setjmp.h>
  30.  
  31. struct private
  32. {
  33.   /* Points to first byte not fetched.  */
  34.   bfd_byte *max_fetched;
  35.   bfd_byte the_buffer[MAXLEN];
  36.   bfd_vma insn_start;
  37.   jmp_buf bailout;
  38. };
  39.  
  40. /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
  41.    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
  42.    on error.  */
  43. #define FETCH_DATA(info, addr) \
  44.   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
  45.    ? 1 : fetch_data ((info), (addr)))
  46.  
  47. static int
  48. fetch_data (info, addr)
  49.      struct disassemble_info *info;
  50.      bfd_byte *addr;
  51. {
  52.   int status;
  53.   struct private *priv = (struct private *)info->private_data;
  54.   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
  55.  
  56.   status = (*info->read_memory_func) (start,
  57.                       priv->max_fetched,
  58.                       addr - priv->max_fetched,
  59.                       info);
  60.   if (status != 0)
  61.     {
  62.       (*info->memory_error_func) (status, start, info);
  63.       longjmp (priv->bailout, 1);
  64.     }
  65.   else
  66.     priv->max_fetched = addr;
  67.   return 1;
  68. }
  69.  
  70. static char *crname[] =
  71. {"sr", "ccr", "*", "br", "ep", "dp", "*", "tp"};
  72.  
  73. int
  74. print_insn_h8500 (addr, info)
  75.      unsigned long addr;
  76.      disassemble_info *info;
  77. {
  78.   h8500_opcode_info *opcode;
  79.   void *stream = info->stream;
  80.   fprintf_ftype func = info->fprintf_func;
  81.  
  82.   struct private priv;
  83.   bfd_byte *buffer = priv.the_buffer;
  84.  
  85.   info->private_data = (PTR) &priv;
  86.   priv.max_fetched = priv.the_buffer;
  87.   priv.insn_start = addr;
  88.   if (setjmp (priv.bailout) != 0)
  89.     /* Error return.  */
  90.     return -1;
  91.  
  92.   /* Run down the table to find the one which matches */
  93.   for (opcode = h8500_table; opcode->name; opcode++)
  94.     {
  95.       int byte;
  96.       int rn;
  97.       int rd;
  98.       int rs;
  99.       int disp;
  100.       int abs;
  101.       int imm;
  102.       int pcrel;
  103.       int qim;
  104.       int i;
  105.       int cr;
  106.       for (byte = 0; byte < opcode->length; byte++)
  107.     {
  108.       FETCH_DATA (info, buffer + byte + 1);
  109.       if ((buffer[byte] & opcode->bytes[byte].mask)
  110.           != (opcode->bytes[byte].contents))
  111.         {
  112.           goto next;
  113.         }
  114.       else
  115.         {
  116.           /* extract any info parts */
  117.           switch (opcode->bytes[byte].insert)
  118.         {
  119.         case 0:
  120.         case FP:
  121.           break;
  122.         default:
  123.           func (stream, "can't cope with insert %d\n",
  124.             opcode->bytes[byte].insert);
  125.           break;
  126.         case RN:
  127.           rn = buffer[byte] & 0x7;
  128.           break;
  129.         case RS:
  130.           rs = buffer[byte] & 0x7;
  131.           break;
  132.         case CRB:
  133.           cr = buffer[byte] & 0x7;
  134.           if (cr == 0)
  135.             goto next;
  136.           break;
  137.         case CRW:
  138.           cr = buffer[byte] & 0x7;
  139.           if (cr != 0)
  140.             goto next;
  141.           break;
  142.         case DISP16:
  143.           FETCH_DATA (info, buffer + byte + 2);
  144.           disp = (buffer[byte] << 8) | (buffer[byte + 1]);
  145.           break;
  146.         case FPIND_D8:
  147.         case DISP8:
  148.           disp = ((char) (buffer[byte]));
  149.           break;
  150.         case RD:
  151.         case RDIND:
  152.           rd = buffer[byte] & 0x7;
  153.           break;
  154.         case ABS24:
  155.           FETCH_DATA (info, buffer + byte + 3);
  156.           abs =
  157.             (buffer[byte] << 16)
  158.             | (buffer[byte + 1] << 8)
  159.             | (buffer[byte + 2]);
  160.           break;
  161.         case ABS16:
  162.           FETCH_DATA (info, buffer + byte + 2);
  163.           abs = (buffer[byte] << 8) | (buffer[byte + 1]);
  164.           break;
  165.         case ABS8:
  166.           abs = (buffer[byte]);
  167.           break;
  168.         case IMM16:
  169.           FETCH_DATA (info, buffer + byte + 2);
  170.           imm = (buffer[byte] << 8) | (buffer[byte + 1]);
  171.           break;
  172.         case IMM4:
  173.           imm = (buffer[byte]) & 0xf;
  174.           break;
  175.         case IMM8:
  176.         case RLIST:
  177.           imm = (buffer[byte]);
  178.           break;
  179.         case PCREL16:
  180.           FETCH_DATA (info, buffer + byte + 2);
  181.           pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);
  182.           break;
  183.         case PCREL8:
  184.           pcrel = (buffer[byte]);
  185.           break;
  186.         case QIM:
  187.           switch (buffer[byte] & 0x7)
  188.             {
  189.             case 0:
  190.               qim = 1;
  191.               break;
  192.             case 1:
  193.               qim = 2;
  194.               break;
  195.             case 4:
  196.               qim = -1;
  197.               break;
  198.             case 5:
  199.               qim = -2;
  200.               break;
  201.             }
  202.           break;
  203.  
  204.         }
  205.         }
  206.     }
  207.       /* We get here when all the masks have passed so we can output the
  208.      operands*/
  209.       FETCH_DATA (info, buffer + opcode->length);
  210.       for (i = 0; i < opcode->length; i++)
  211.     {
  212.       (func) (stream, "%02x ", buffer[i]);
  213.     }
  214.       for (; i < 6; i++)
  215.     {
  216.       (func) (stream, "   ");
  217.     }
  218.       (func) (stream, "%s\t", opcode->name);
  219.       for (i = 0; i < opcode->nargs; i++)
  220.     {
  221.       if (i)
  222.         (func) (stream, ",");
  223.       switch (opcode->arg_type[i])
  224.         {
  225.         case FP:
  226.           func (stream, "fp");
  227.           break;
  228.         case RNIND_D16:
  229.           func (stream, "@(0x%x:16,r%d)", disp, rn);
  230.           break;
  231.         case RNIND_D8:
  232.           func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
  233.           break;
  234.         case RDIND_D16:
  235.           func (stream, "@(0x%x:16,r%d)", disp, rd);
  236.           break;
  237.         case RDIND_D8:
  238.           func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
  239.           break;
  240.         case FPIND_D8:
  241.           func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp, rn);
  242.           break;
  243.         case CRB:
  244.         case CRW:
  245.           func (stream, "%s", crname[cr]);
  246.           break;
  247.         case RN:
  248.           func (stream, "r%d", rn);
  249.           break;
  250.         case RD:
  251.           func (stream, "r%d", rd);
  252.           break;
  253.         case RS:
  254.           func (stream, "r%d", rs);
  255.           break;
  256.         case RNDEC:
  257.           func (stream, "@-r%d", rn);
  258.           break;
  259.         case RNINC:
  260.           func (stream, "@r%d+", rn);
  261.           break;
  262.         case RNIND:
  263.           func (stream, "@r%d", rn);
  264.           break;
  265.         case RDIND:
  266.           func (stream, "@r%d", rd);
  267.           break;
  268.         case SPINC:
  269.           func (stream, "@sp+");
  270.           break;
  271.         case SPDEC:
  272.           func (stream, "@-sp");
  273.           break;
  274.         case ABS24:
  275.           func (stream, "@0x%0x:24", abs);
  276.           break;
  277.         case ABS16:
  278.           func (stream, "@0x%0x:16", abs & 0xffff);
  279.           break;
  280.         case ABS8:
  281.           func (stream, "@0x%0x:8", abs & 0xff);
  282.           break;
  283.         case IMM16:
  284.           func (stream, "#0x%0x:16", imm & 0xffff);
  285.           break;
  286.         case RLIST:
  287.           {
  288.         int i;
  289.         int nc = 0;
  290.         func (stream, "(");
  291.         for (i = 0; i < 8; i++)
  292.           {
  293.             if (imm & (1 << i))
  294.               {
  295.             if (nc)
  296.               func (stream, ",");
  297.             nc += 1;
  298.               }
  299.             func (stream, "r%d", i);
  300.           }
  301.         func (stream, ")");
  302.           }
  303.           break;
  304.         case IMM8:
  305.           func (stream, "#0x%0x:8", imm & 0xff);
  306.           break;
  307.         case PCREL16:
  308.           func (stream, "0x%0x:16", (pcrel + addr + opcode->length) & 0xffff);
  309.           break;
  310.         case PCREL8:
  311.           func (stream, "#0x%0x:8",
  312.             ((char) pcrel + addr + opcode->length) & 0xffff);
  313.           break;
  314.         case QIM:
  315.           func (stream, "#%d:q", qim);
  316.           break;
  317.         case IMM4:
  318.           func (stream, "#%d:4", imm);
  319.           break;
  320.         }
  321.     }
  322.       return opcode->length;
  323.     next:;
  324.     }
  325.  
  326.   /* Couldn't understand anything */
  327.   func (stream, "%02x\t\t*unknown*", buffer[0]);
  328.   return 1;
  329.  
  330. }
  331.